package com.excel.easyExcel.service.Impl;

import com.alibaba.excel.EasyExcel;
import com.excel.easyExcel.entity.Goods;
import com.excel.easyExcel.exception.ImportException;
import com.excel.easyExcel.mapper.GoodsMapper;
import com.excel.easyExcel.service.GoodsService;
import com.excel.easyExcel.utils.ExcelReadListener;
import com.excel.easyExcel.vo.ExportVo;
import com.excel.easyExcel.vo.ImportVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Xinjie
 * @date 2023/4/25 11:50
 */
@Service
@Slf4j
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private GoodsMapper goodsMapper;

    @SneakyThrows
    @Override
    public boolean importExcel(MultipartFile excel) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
        ExcelReadListener<ImportVo> readListener = new ExcelReadListener<>();
        InputStream inputStream = excel.getInputStream();
        EasyExcel.read(inputStream, ImportVo.class, readListener).sheet().doRead();
        inputStream.close();
        List<ImportVo> importVos = readListener.getData();
        for (ImportVo importVo : importVos) {
            Goods goods = new Goods();
            BeanUtils.copyProperties(importVo, goods);
            Date parse = simpleDateFormat.parse(importVo.getDate());
            goods.setTimestamp(parse.getTime());
            int insert = goodsMapper.insert(goods);
            if (insert <= 0) {
                throw new ImportException("数据库传输错误");
            }
        }
        return true;
    }

    @SneakyThrows
    @Override
    public List<ExportVo> exportExcel(Long sd, Long ed) {
        //每个月时间戳
        long month = 2592000000L;
        List<ExportVo> exportVos = new ArrayList<>();
        List<Goods> goods = goodsMapper.getAllByTimestamp(sd, ed);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-M");
        String s = simpleDateFormat.format(new Date(sd));
        String e = simpleDateFormat.format(new Date(ed));
        Map<String, Map<String, Map<String, List<Goods>>>> nameMap = goods.parallelStream().sorted(Comparator.comparing(Goods::getTimestamp))
                .collect(Collectors.groupingBy(Goods::getName, Collectors.groupingBy(Goods::getToCity, Collectors.groupingBy(o -> {
                    if (!s.equals(e) && ed - month > sd) {
                        int i = 1;
                        while (o.getTimestamp() >= sd + month * i) {
                            i++;
                        }
                        return simpleDateFormat.format(new Date(sd + (i - 1) * month));
                    }
                    return s;
                }))));
        Set<String> nameKey = nameMap.keySet();
        for (String key1 : nameKey) {
            Map<String, Map<String, List<Goods>>> toMap = nameMap.get(key1);
            Set<String> toKey = toMap.keySet();
            for (String key2 : toKey) {
                Map<String, List<Goods>> timeMap = toMap.get(key2);
                Set<String> timeKey = timeMap.keySet();
                for (String key3 : timeKey) {
                    List<Goods> goodsList = timeMap.get(key3);
                    BigInteger reduce = goodsList.stream().map(Goods::getGoodsNumber).reduce(BigInteger.ZERO, BigInteger::add);
//                    BigInteger reduce = new BigInteger("0");
//                    for (Goods goods1 : goodsList) {
//                        reduce = reduce.add(goods1.getGoodsNumber());
//                    }
                    ExportVo exportVo = new ExportVo();
                    Goods goods1 = goodsList.get(0);
                    BeanUtils.copyProperties(goods1, exportVo);
                    exportVo.setGoodsNumber(reduce);
                    exportVo.setMonth(key3);
                    exportVos.add(exportVo);
                }
            }
        }
        return exportVos;
    }
}
